#include "Alarms.h"

ALARM *alarmSchedule[fifoSize];
ALARM ALARM_A;
COUNTER SYSTEMTIMER;

void SetRelAlarm(ALARM* AlarmID, unsigned int IncrementTicks, 
unsigned int CycleTicks)
{
  unsigned char posAlarmSchedule=9;  
  do
  {
    if(alarmSchedule[posAlarmSchedule]==AlarmID)
    {
      AlarmID -> cycleTicks = CycleTicks;
      AlarmID -> incrementTicks = IncrementTicks;
      AlarmID -> startTicks = 0;
      AlarmID -> CRONO = AlarmID ->cycleTicks;
      return;
    }
  }while(posAlarmSchedule--);    
  posAlarmSchedule=9;  
  do
  {
    if(alarmSchedule[posAlarmSchedule]==NULL){
      AlarmID -> cycleTicks = CycleTicks;
      AlarmID -> incrementTicks = IncrementTicks;
      AlarmID -> startTicks = 0;
      AlarmID -> CRONO = AlarmID ->cycleTicks;
      AlarmID -> started = 0;
      alarmSchedule[posAlarmSchedule]=AlarmID;
      break;
    }
  }while(posAlarmSchedule--);   
}

void SetAbsAlarm(ALARM* AlarmID, unsigned int StartTicks, 
unsigned int CycleTicks)
{
  unsigned char posAlarmSchedule=9;  
  do
  {
    if(alarmSchedule[posAlarmSchedule]==AlarmID)
    {
      AlarmID -> cycleTicks = CycleTicks;
      AlarmID -> incrementTicks = 0;
      AlarmID -> startTicks = StartTicks ;
      AlarmID -> CRONO = AlarmID ->cycleTicks;
      return;
    }
  }while(posAlarmSchedule--);    
  posAlarmSchedule=9;
  do
  {
    if(alarmSchedule[posAlarmSchedule]==NULL)
    {
      AlarmID -> cycleTicks = CycleTicks;
      AlarmID -> incrementTicks = 0;
      AlarmID -> startTicks = StartTicks ;
      AlarmID -> CRONO = AlarmID ->cycleTicks;
      AlarmID -> started = 0;
      alarmSchedule[posAlarmSchedule]=AlarmID;
      break;
    }
  }while(posAlarmSchedule--);  
}

void CancelAlarm (ALARM* AlarmID)
{
  unsigned char posAlarmSchedule=9;  
  do
  {
    if(alarmSchedule[posAlarmSchedule]==AlarmID)
    {
      alarmSchedule[posAlarmSchedule]= NULL;
      break;
    }
  }while(posAlarmSchedule--);  
}

void alarmAction(void)
{
  /* If one tick is presented */
  if(tickCounter == SYSTEMTIMER.TICKSPERBASE)
  {
    /* Restart the tickcounter */
    tickCounter=0;
    baseTickCounter++;
    /* A tick is presented */
    alarmIndex=9;    
    do
    {
      /* If there is an alarm in this position */
      if(alarmSchedule[alarmIndex] != NULL)
      {
        if(alarmSchedule[alarmIndex]->started)
        {          
          if(alarmSchedule[alarmIndex]->cycleTicks)
          {  
            alarmSchedule[alarmIndex]->CRONO--;            
            /* Verifico si existe una alarma ciclica */            
            if(!alarmSchedule[alarmIndex]->CRONO)
            {
              alarmSchedule[alarmIndex]->CRONO=alarmSchedule[alarmIndex]->
              cycleTicks;
              /* Ejecuto la accion de la alarma */
              /* Inserto la tarea si no fue insertada */
              if(insertTaskByAlarm())
              {
                interruptActivateTask(alarmSchedule[alarmIndex]->TASK_ALARM);  
              }
            }            
          }            
        }
        else
        {
        /* Se ejecuta la fisrt alarm */         
          /* Increment -> relative */
          /* Start     -> absolute */   
          if(alarmSchedule[alarmIndex]->startTicks)
          {
            /* Alarmas absolutas primer vez             
             * si counside con baseTickCounter se dispara la alarma */
            if(baseTickCounter==alarmSchedule[alarmIndex]->startTicks)
            {
              alarmSchedule[alarmIndex]->started=1;
              /* Ejecuto la accion de la alarma 
               * inserto la tarea si no fue insertada */
              if(insertTaskByAlarm())
              {
                interruptActivateTask(alarmSchedule[alarmIndex]->TASK_ALARM);  
              }
            }              
          }
          else
          {
          /* Alarmas relativas primer vez */
             alarmSchedule[alarmIndex]->incrementTicks--;
             if(!alarmSchedule[alarmIndex]->incrementTicks)
             {
                alarmSchedule[alarmIndex]->started=1;
                /* Ejecuto la accion de la alarma */
                /* Inserto la tarea si no fue insertada */
                if(insertTaskByAlarm())
                {
                  interruptActivateTask(alarmSchedule[alarmIndex]->TASK_ALARM);  
                }
             }      
          }
        }
      }
    }while(alarmIndex--);
  } 
}

unsigned char insertTaskByAlarm(void)
{
  if(size)
  {
    taskIndex=size-1;
    do
    {
      if((fptr+taskIndex)->u8functionID == 
      alarmSchedule[alarmIndex]->TASK_ALARM->u8functionID)
      {
        return TRUE;                                               
      }                                             
    }while(taskIndex);
    return FALSE;
  }
  else
  {
    return TRUE;
  }
}
